#include "Application.hpp"
#include "SDL2/SDL_opengl.h"
#include <iostream>

_NNU_DGGS_BEGIN
namespace DGGSViewer
{
    Application::Application()
        : m_running(false),
          m_window(nullptr),
          m_renderer(nullptr),
          m_glContext(nullptr),
          m_windowWidth(800),
          m_windowHeight(600),
          m_isFullscreen(false),
          m_mouseLeftDown(false),
          m_mouseLastX(0),
          m_mouseLastY(0)
    {
    }

    Application::~Application()
    {
        cleanup();
    }

    bool Application::initialize()
    {
        if (SDL_Init(SDL_INIT_VIDEO) < 0)
        {
            std::cerr << "SDL初始化失败: " << SDL_GetError() << std::endl;
            return false;
        }

        // 设置OpenGL属性
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

        m_window = SDL_CreateWindow(
            "OpenDGGS-Visualizer",
            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            m_windowWidth, m_windowHeight,
            SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
        );

        if (!m_window)
        {
            std::cerr << "窗口创建失败: " << SDL_GetError() << std::endl;
            return false;
        }

        m_glContext = SDL_GL_CreateContext(m_window);
        if (!m_glContext)
        {
            std::cerr << "OpenGL上下文创建失败: " << SDL_GetError() << std::endl;
            return false;
        }

        // 初始化组件
        m_earth = std::make_unique<Earth>();
        m_fileHandler = std::make_unique<FileHandler>();
        m_inputHandler = std::make_unique<InputHandler>();

        if (!m_earth->initialize())
        {
            std::cerr << "地球初始化失败" << std::endl;
            return false;
        }

        return true;
    }

    void Application::cleanup() const
    {
        if (m_glContext)
        {
            SDL_GL_DeleteContext(m_glContext);
        }

        if (m_window)
        {
            SDL_DestroyWindow(m_window);
        }

        SDL_Quit();
    }

    int Application::run()
    {
        if (!initialize())
        {
            return 1;
        }

        m_running = true;

        while (m_running)
        {
            processEvents();
            render();
        }

        return 0;
    }

    void Application::processEvents()
    {
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
                m_running = false;
            }

            // 处理窗口事件
            if (event.type == SDL_WINDOWEVENT)
            {
                if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
                {
                    m_windowWidth = event.window.data1;
                    m_windowHeight = event.window.data2;
                    handleWindowResize(m_windowWidth, m_windowHeight);
                }
            }

            // 处理键盘输入
            if (event.type == SDL_KEYDOWN)
            {
                // Tab键处理 - 切换快捷键说明显示
                if (event.key.keysym.sym == SDLK_TAB)
                {
                    m_earth->toggleHelpText();
                    continue;
                }
                
                // G键处理 - 切换经纬网显示
                if (event.key.keysym.sym == SDLK_g)
                {
                    m_earth->toggleGrid();
                    continue;
                }
                
                // L键处理 - 切换经纬网标注显示
                if (event.key.keysym.sym == SDLK_l)
                {
                    m_earth->toggleGridLabels();
                    continue;
                }
                
                // 直接处理方向键上下键
                if (event.key.keysym.sym == SDLK_UP || event.key.keysym.sym == SDLK_DOWN)
                {
                    // 直接传递到Earth处理透明度调整
                    m_earth->handleKeyboard(event.key.keysym.sym);
                }
                else
                {
                    char key = m_inputHandler->handleKeyEvent(event);
                    if (key == 'o')
                    {
                        // 检查是否同时按下了Shift键
                        const Uint8* keyState = SDL_GetKeyboardState(nullptr);
                        if (keyState[SDL_SCANCODE_LSHIFT] || keyState[SDL_SCANCODE_RSHIFT])
                        {
                            handleMultipleFilesOpen();
                        }
                        else
                        {
                            handleFileOpen();
                        }
                    }
                    else if (key == 'm')
                    {
                        // 直接触发多文件选择
                        handleMultipleFilesOpen();
                    }
                    else if (key == 'q')
                    {
                        m_running = false;
                    }
                    else if (key == 'r')
                    {
                        // 重置视图
                        m_earth->resetView();
                    }
                    else if (key == 'f')
                    {
                        // 切换全屏模式
                        toggleFullscreen();
                    }
                    else if (key == 'p')
                    {
                        // 切换性能监控显示
                        static bool showPerformance = true;
                        showPerformance = !showPerformance;
                        std::cout << "性能监控显示: " << (showPerformance ? "开启" : "关闭") << std::endl;
                    }
                    else if (key >= '1' && key <= '7')
                    {
                        // 处理色带切换，将键码直接传给Earth
                        m_earth->handleKeyboard(event.key.keysym.sym);
                    }
                }
            }

            // 处理鼠标滚轮事件
            if (event.type == SDL_MOUSEWHEEL)
            {
                m_earth->handleMouseWheel(static_cast<float>(event.wheel.y));
            }

            // 处理鼠标按下事件
            if (event.type == SDL_MOUSEBUTTONDOWN)
            {
                if (event.button.button == SDL_BUTTON_LEFT)
                {
                    m_mouseLeftDown = true;
                    m_mouseLastX = event.button.x;
                    m_mouseLastY = event.button.y;
                }
            }

            // 处理鼠标释放事件
            if (event.type == SDL_MOUSEBUTTONUP)
            {
                if (event.button.button == SDL_BUTTON_LEFT)
                {
                    // 如果鼠标没有拖动太多，视为点击事件
                    if (std::abs(event.button.x - m_mouseLastX) < 5 && std::abs(event.button.y - m_mouseLastY) < 5)
                    {
                        // 调用Earth类的handleMouseClick方法获取经纬度
                        GeoCoordinate coord = m_earth->handleMouseClick(event.button.x, event.button.y);

                        // 如果获取到有效经纬度，可以做额外处理
                        if (coord.isValid)
                        {
                            std::cout << "点击位置的经纬度: 纬度=" << coord.lat << ", 经度=" << coord.lon << std::endl;
                        }
                    }

                    m_mouseLeftDown = false;
                }
            }

            // 处理鼠标移动事件
            if (event.type == SDL_MOUSEMOTION)
            {
                if (m_mouseLeftDown)
                {
                    int xRel = event.motion.x - m_mouseLastX;
                    int yRel = event.motion.y - m_mouseLastY;

                    m_earth->handleMouseDrag(xRel, yRel, true);

                    m_mouseLastX = event.motion.x;
                    m_mouseLastY = event.motion.y;
                }
            }
        }
    }

    void Application::render()
    {
        // 清除屏幕
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // 渲染地球
        m_earth->render();

        // 交换缓冲区
        SDL_GL_SwapWindow(m_window);
    }

    void Application::handleFileOpen() const
    {
        if (const std::string filePath = FileHandler::showOpenFileDialog(); !filePath.empty())
        {
            m_earth->loadData(filePath);
        }
    }

    void Application::handleMultipleFilesOpen() const
    {
        if (const std::vector<std::string> filePaths = FileHandler::showOpenMultipleFilesDialog(); !filePaths.empty())
        {
            std::cout << "选择了 " << filePaths.size() << " 个文件" << std::endl;

            m_earth->loadMultipleData(filePaths);
        }
    }

    void Application::toggleFullscreen()
    {
        m_isFullscreen = !m_isFullscreen;

        if (m_isFullscreen)
        {
            SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
        }
        else
        {
            SDL_SetWindowFullscreen(m_window, 0);
        }

        // 获取新的窗口大小
        SDL_GetWindowSize(m_window, &m_windowWidth, &m_windowHeight);
        handleWindowResize(m_windowWidth, m_windowHeight);
    }

    void Application::handleWindowResize(const int width, const int height) const
    {
        // 更新地球的投影矩阵
        m_earth->updateProjection(width, height);
    }
} // namespace DGGSV
_NNU_DGGS_END